/**
 * 工具服务
 * 提供文件处理和图片处理功能
 */

/**
 * 文件重命名选项
 */
export interface RenameOptions {
  removeChinese?: boolean;
  replaceSpaces?: boolean;
  replaceWith?: string;
  prefix?: string;
  suffix?: string;
}

/**
 * 工具服务类
 */
class ToolsService {
  /**
   * 清理文件名
   */
  private sanitizeFileName(fileName: string, options: RenameOptions = {}): string {
    const {
      removeChinese = true,
      replaceSpaces = true,
      replaceWith = '_'
    } = options;

    let sanitized = fileName;

    // 移除中文字符
    if (removeChinese) {
      sanitized = sanitized.replace(/[\u4e00-\u9fa5]/g, '');
    }

    // 替换或删除空格
    if (replaceSpaces) {
      if (replaceWith === '') {
        // 如果替换字符为空，直接删除空格
        sanitized = sanitized.replace(/\s+/g, '');
      } else {
        // 否则用指定字符替换空格
        sanitized = sanitized.replace(/\s+/g, replaceWith);
      }
    }

    // 清理多个连续的特殊字符
    if (replaceWith !== '') {
      sanitized = sanitized.replace(/[_\-]{2,}/g, replaceWith);
    }

    // 移除开头和结尾的特殊字符
    sanitized = sanitized.replace(/^[_\-]+|[_\-]+$/g, '');

    return sanitized;
  }

  /**
   * 批量重命名文件
   */
  async batchRenameFiles(files: File[], options: RenameOptions = {}): Promise<{originalName: string, newName: string}[]> {
    const results: {originalName: string, newName: string}[] = [];

    for (const file of files) {
      const newName = this.sanitizeFileName(file.name, options);
      results.push({
        originalName: file.name,
        newName: newName
      });
    }

    return results;
  }

  /**
   * 裁剪图片
   */
  async cropImage(
    file: File, 
    options: {
      width?: number;
      height?: number;
      x?: number;
      y?: number;
      aspectRatio?: number;
    } = {}
  ): Promise<Blob> {
    return new Promise((resolve, reject) => {
      const img = new Image();
      const url = URL.createObjectURL(file);

      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');

        if (!ctx) {
          URL.revokeObjectURL(url);
          reject(new Error('无法创建canvas上下文'));
          return;
        }

        let { width, height, x = 0, y = 0 } = options;

        // 如果没有指定尺寸，使用智能裁剪
        if (!width || !height) {
          if (options.aspectRatio) {
            // 按宽高比裁剪
            const aspectRatio = options.aspectRatio;
            const imgAspectRatio = img.width / img.height;

            if (imgAspectRatio > aspectRatio) {
              // 图片更宽，按高度裁剪
              height = img.height;
              width = height * aspectRatio;
              x = (img.width - width) / 2;
            } else {
              // 图片更高，按宽度裁剪
              width = img.width;
              height = width / aspectRatio;
              y = (img.height - height) / 2;
            }
          } else {
            // 默认中心正方形裁剪
            const size = Math.min(img.width, img.height);
            width = height = size;
            x = (img.width - size) / 2;
            y = (img.height - size) / 2;
          }
        }

        canvas.width = width;
        canvas.height = height;

        // 执行裁剪
        ctx.drawImage(img, x, y, width, height, 0, 0, width, height);

        // 转换为blob
        canvas.toBlob((blob) => {
          URL.revokeObjectURL(url);
          if (blob) {
            resolve(blob);
          } else {
            reject(new Error('无法创建图片blob'));
          }
        }, file.type || 'image/jpeg', 0.9);
      };

      img.onerror = () => {
        URL.revokeObjectURL(url);
        reject(new Error('无法加载图片文件'));
      };

      img.src = url;
    });
  }

  /**
   * 批量裁剪图片
   */
  async batchCropImages(
    files: File[], 
    options: {
      width?: number;
      height?: number;
      x?: number;
      y?: number;
      aspectRatio?: number;
      onProgress?: (progress: number) => void;
    } = {}
  ): Promise<{file: File, blob: Blob}[]> {
    const results: {file: File, blob: Blob}[] = [];
    const total = files.length;

    for (let i = 0; i < total; i++) {
      try {
        const blob = await this.cropImage(files[i], options);
        results.push({
          file: files[i],
          blob
        });

        // 更新进度
        if (options.onProgress) {
          options.onProgress(((i + 1) / total) * 100);
        }
      } catch (error) {
        console.error(`处理文件 ${files[i].name} 失败:`, error);
        throw error;
      }
    }

    return results;
  }

  /**
   * 下载文件
   */
  downloadFile(blob: Blob, fileName: string): void {
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  /**
   * 批量下载文件
   */
  async downloadFiles(files: {file: File, blob: Blob}[]): Promise<void> {
    // 跟踪已使用的文件名以避免冲突
    const usedFileNames = new Set<string>();
    
    for (const {file, blob} of files) {
      let fileName = `cropped_${file.name}`;
      const baseName = `cropped_${file.name}`;
      let counter = 1;
      
      // 检查文件名是否已存在，如果存在则添加序号
      while (usedFileNames.has(fileName)) {
        const nameParts = baseName.split('.');
        if (nameParts.length > 1) {
          const extension = nameParts.pop();
          const nameWithoutExtension = nameParts.join('.');
          fileName = `${nameWithoutExtension}(${counter}).${extension}`;
        } else {
          fileName = `${baseName}(${counter})`;
        }
        counter++;
      }
      
      // 记录已使用的文件名
      usedFileNames.add(fileName);
      
      this.downloadFile(blob, fileName);
      
      // 添加小延迟避免浏览器阻止多个下载
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }
}

export default new ToolsService();